using ICSharpCode.TextEditor.Document;

namespace ICSharpCode.TextEditor.Actions
{
    public class Backspace : AbstractEditAction
    {
        public override void Execute(TextArea textArea)
        {
            checked
            {
                if (textArea.SelectionManager.HasSomethingSelected && (!textArea.SelectionManager.IsMutilSelect || textArea.SelectionManager.HasSomethingMutilLinesSeleted))
                {
                    Delete.DeleteSelection(textArea);
                }
                else
                {
                    if (textArea.Caret.Offset <= 0 || textArea.IsReadOnly(textArea.Caret.Offset - 1))
                    {
                        return;
                    }
                    textArea.BeginUpdate();
                    int num = 0;
                    int num2 = 0;
                    if (!textArea.SelectionManager.IsMutilSelect)
                    {
                        num = textArea.Document.GetLineNumberForOffset(textArea.Caret.Offset);
                        num2 = textArea.Document.GetLineSegment(num).Offset;
                        if (num2 == textArea.Caret.Offset)
                        {
                            LineSegment lineSegment = textArea.Document.GetLineSegment(num - 1);
                            bool flag = num == textArea.Document.TotalNumberOfLines;
                            int num3 = lineSegment.Offset + lineSegment.Length;
                            int length = lineSegment.Length;
                            textArea.Document.Remove(num3, num2 - num3);
                            textArea.Caret.Position = new TextLocation(length, num - 1);
                            textArea.Document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.PositionToEnd, new TextLocation(0, num - 1)));
                        }
                        else
                        {
                            int offset = textArea.Caret.Offset - 1;
                            textArea.Caret.Position = textArea.Document.OffsetToPosition(offset);
                            textArea.Document.Remove(offset, 1);
                            textArea.Document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.PositionToLineEnd, new TextLocation(textArea.Caret.Offset - textArea.Document.GetLineSegment(num).Offset, num)));
                        }
                    }
                    else
                    {
                        int num4 = textArea.Document.PositionToOffset(textArea.SelectionManager.SelectionStart);
                        int num5 = textArea.Document.PositionToOffset(textArea.SelectionManager.SelectionEnd);
                        if (textArea.SelectionManager.SelectionStart.Column > 0 && textArea.SelectionManager.SelectionEnd.Column > 0)
                        {
                            textArea.SelectionManager.SelectionStart = textArea.Document.OffsetToPosition(num4 - 1);
                            textArea.SelectionManager.SelectionEnd = textArea.Document.OffsetToPosition(num5 - 1);
                            foreach (ISelection item in textArea.SelectionManager.selectionCollection)
                            {
                                num = textArea.Document.GetLineNumberForOffset(item.Offset);
                                num2 = textArea.Document.GetLineSegment(num).Offset;
                                num4 = textArea.Document.PositionToOffset(item.StartPosition);
                                num5 = textArea.Document.PositionToOffset(item.EndPosition);
                                if (num2 == item.Offset)
                                {
                                    LineSegment lineSegment2 = textArea.Document.GetLineSegment(num - 1);
                                    bool flag2 = num == textArea.Document.TotalNumberOfLines;
                                    int num6 = lineSegment2.Offset + lineSegment2.Length;
                                    int length2 = lineSegment2.Length;
                                    textArea.Document.Remove(num6, num2 - num6);
                                    textArea.Caret.Position = new TextLocation(length2, num - 1);
                                    item.StartPosition = new TextLocation(length2, num - 1);
                                    item.EndPosition = new TextLocation(length2, num - 1);
                                    continue;
                                }
                                LineSegment lineSegment3 = textArea.Document.GetLineSegment(num);
                                int offset2 = num4 - 1;
                                textArea.Caret.Position = textArea.Document.OffsetToPosition(offset2);
                                int num7 = lineSegment3.Offset + lineSegment3.Length;
                                int num8 = textArea.Document.PositionToOffset(new TextLocation(textArea.SelectionManager.SelectionStart.Column, item.StartPosition.Line));
                                if (num7 > num8)
                                {
                                    textArea.Document.Remove(offset2, 1);
                                    num4--;
                                    num5--;
                                    item.StartPosition = textArea.Document.OffsetToPosition(num4);
                                    item.EndPosition = textArea.Document.OffsetToPosition(num5);
                                }
                            }
                            textArea.Document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.LinesBetween, textArea.SelectionManager.SelectionStart.Line, textArea.SelectionManager.SelectionEnd.Line));
                        }
                    }
                    textArea.EndUpdate();
                }
            }
        }
    }
}
